﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using SDG.Common;
using System.Net;
using System.Web.Script.Serialization;
using Sdo.LoginHelper;
using System.Reflection;

namespace Common
{

    ///CheckInfo 验证帮助类
    /// <summary>
    ///CheckInfo 验证帮助类
    /// </summary>
    public class CheckInfo
    {
        public CheckInfo()
        {

        }

        #region 验证

        /// <summary>
        /// 手机号验证
        /// </summary>
        /// <param name="Mobile"></param>
        /// <returns></returns>
        public static bool IsMobile(string Mobile)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(Mobile, @"^[1][3-9][0-9]{9}$") && Mobile.Length == 11;
        }

        /// <summary>
        /// 邮箱验证
        /// </summary>
        /// <param name="Mobile"></param>
        /// <returns></returns>
        public static bool IsEmail(string email)
        {
            String ZipRegex = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            if (System.Text.RegularExpressions.Regex.IsMatch(email, ZipRegex))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion 验证

        #region 不同类型间转换

        /// <summary>
        /// 将数据导出为json格式字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static string JsonSerializer<T>(T t)
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            MemoryStream ms = new MemoryStream();
            ser.WriteObject(ms, t);
            string jsonString = Encoding.UTF8.GetString(ms.ToArray());
            ms.Close();
            return jsonString;
        }

        /// 反序列化
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        public static T JsonDeserialize<T>(string jsonString)
        {
            JavaScriptSerializer Serializer = new JavaScriptSerializer();
            StringBuilder outJson = new StringBuilder();
            return Serializer.Deserialize<T>(jsonString);
        }

        /// 反序列化
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        public static T JsonDeserializeMax<T>(string jsonString)
        {
            JavaScriptSerializer Serializer = new JavaScriptSerializer();
            Serializer.MaxJsonLength = Int32.MaxValue;
            StringBuilder outJson = new StringBuilder();
            return Serializer.Deserialize<T>(jsonString);
        }

        /// mysql的latin1转UTF8
        /// <summary>
        /// mysql的latin1转UTF8
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string turnlatin1string(string source)
        {
            var en = System.Text.Encoding.GetEncoding("latin1");
            var bs = en.GetBytes(source);
            var a = System.Text.Encoding.Default.GetString(bs);
            return a;
        }

        /// DateTime转化为UTC时间
        /// <summary>
        /// DateTime转化为UTC时间
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static long ConvertTimeToUTCTimeStamp(DateTime time)
        {
            long a = 0;
            if (time != null && time.ToString() != "")
            {
                DateTime timeStamp = new DateTime(1970, 1, 1);
                a = (long)(time.ToUniversalTime() - timeStamp).TotalSeconds;
            }
            return a;
        }

        /// 获取时间UTC int型
        /// <summary>
        /// 获取时间UTC int型
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static int GetServiceTimeStamp()
        {
            return (int)((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000L) / 10000000L);
        }

        public static long GetServiceMilliSecond()
        {
            return (long)((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000L) / 10000L);
        }

        /// UTC转化为DateTime
        /// <summary>
        /// UTC转化为DateTime
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public static DateTime ConvertUTCTimeStampToDateTime(double d)
        {
            DateTime timeStamp = new DateTime(1970, 1, 1);
            DateTime time = timeStamp.AddSeconds(d).ToLocalTime();
            return time;
        }

        ///// 字典类型转化为对象
        ///// <summary>
        ///// 字典类型转化为对象
        ///// </summary>
        ///// <param name="dic"></param>
        ///// <returns></returns>
        //public T DicToObject<T>(Dictionary<string, object> dic) where T : new()
        //{
        //    var md = new T();
        //    CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
        //    TextInfo textInfo = cultureInfo.TextInfo;
        //    foreach (var d in dic)
        //    {
        //        var filed = textInfo.ToTitleCase(d.Key);
        //        try
        //        {
        //            var value = d.Value;
        //            md.GetType().GetProperty(filed).SetValue(md, value);
        //        }
        //        catch (Exception e)
        //        {

        //        }
        //    }
        //    return md;
        //}

        /// 字典转换为对象
        /// <summary>
        /// 字典转换为对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dic"></param>
        /// <returns></returns>
        public static T DicToObject<T>(Dictionary<string, object> dic)
        {
            T model = Activator.CreateInstance<T>();
            PropertyInfo[] modelPro = model.GetType().GetProperties();
            if (modelPro.Length > 0 && dic.Count() > 0)
            {
                for (int i = 0; i < modelPro.Length; i++)
                {
                    if (dic.ContainsKey(modelPro[i].Name))
                    {
                        modelPro[i].SetValue(model, dic[modelPro[i].Name], null);
                    }
                }
            }
            return model;
        }

        /// <summary>
        /// 对象转换为字典
        /// </summary>
        /// <param name="obj">待转化的对象</param>
        /// <param name="isIgnoreNull">是否忽略NULL 这里我不需要转化NULL的值，正常使用可以不穿参数 默认全转换</param>
        /// <returns></returns>
        public static Dictionary<string, object> ObjectToDic(object obj, bool isIgnoreNull = false)
        {
            Dictionary<string, object> map = new Dictionary<string, object>();

            Type t = obj.GetType(); // 获取对象对应的类， 对应的类型

            PropertyInfo[] pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance); // 获取当前type公共属性

            foreach (PropertyInfo p in pi)
            {
                MethodInfo m = p.GetGetMethod();

                if (m != null && m.IsPublic)
                {
                    // 进行判NULL处理 
                    if (m.Invoke(obj, new object[] { }) != null || !isIgnoreNull)
                    {
                        map.Add(p.Name, m.Invoke(obj, new object[] { })); // 向字典添加元素
                    }
                }
            }
            return map;
        }

        #endregion 不同类型间转换

        #region 加密算法

        /// md5加密
        /// <summary>
        /// md5加密
        /// </summary>
        /// <param name="str"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string md5(string str, int code)
        {
            if (code == 16) //16位MD5加密（取32位加密的9~25字符） 
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower().Substring(8, 16);
            }
            else//32位加密 
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower();
            }
        }

        /// 与PHP兼容的MD5加密
        /// <summary>
        /// 与PHP兼容的MD5加密
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string MD5(string password)
        {

            byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(password);
            try
            {
                System.Security.Cryptography.MD5CryptoServiceProvider cryptHandler;
                cryptHandler = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] hash = cryptHandler.ComputeHash(textBytes);
                string ret = "";
                foreach (byte a in hash)
                {
                    if (a < 16)
                        ret += "0" + a.ToString("x");
                    else
                        ret += a.ToString("x");
                }
                return ret;
            }
            catch
            {
                throw;
            }
        }

        /// SHA1加密
        /// <summary>
        /// SHA1加密
        /// </summary>
        /// <param name="Source_String"></param>
        /// <returns></returns>
        public static string SHA1_Encrypt(string Source_String)
        {
            byte[] StrRes = Encoding.Default.GetBytes(Source_String);
            HashAlgorithm iSHA = new SHA1CryptoServiceProvider();
            StrRes = iSHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte iByte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", iByte);
            }
            return EnText.ToString();
        }

        /// 签名
        /// <summary>
        /// 签名
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private string MakeSign(IList<QueryParameter> parameters)
        {
            string md5Str = NormalizeRequestParameters(parameters);
            var _sign = MD5(md5Str).ToLower();
            return _sign;
        }

        /// 参数拼接
        /// <summary>
        /// 参数拼接
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private string NormalizeRequestParameters(IList<QueryParameter> parameters)
        {
            StringBuilder sb = new StringBuilder();
            QueryParameter p = null;
            for (int i = 0; i < parameters.Count; i++)
            {
                p = parameters[i];
                sb.AppendFormat("{0}={1}", p.Name, p.Value);
            }
            return sb.ToString();
        }

        /// 参数首字母排序
        /// <summary>
        /// 参数首字母排序
        /// </summary>
        /// <param name="tmpList"></param>
        /// <returns></returns>
        public static string SortListToString(List<string> tmpList)
        {
            tmpList.Sort((Comparison<string>)delegate(string a, string b)
            {
                return a.CompareTo(b);
            });

            string tmpStr = string.Empty;
            foreach (string str in tmpList)
            {
                tmpStr += str;
            }

            return tmpStr;
        }

        #endregion 加密算法

        /// 获得客户端IP
        /// <summary>
        /// 获得客户端IP
        /// </summary>
        /// <returns></returns>
        public static string GetClientIP()
        {
            string IPs = HttpContext.Current.Request.ServerVariables["HTTP_Cdn-Src-Ip"];
            if (string.IsNullOrEmpty(IPs)) return WebPageHelper.GetClientIp();
            string[] arr = IPs.Replace(" ", "").Split(',');
            return arr[0];
        }

        /// 是否允许显示错误信息
        /// <summary>
        /// 是否允许显示错误信息
        /// </summary>
        /// <returns></returns>
        public static Boolean CanShowError()
        {
            string IP = GetClientIP();
            if (CheckInfo.IsLocal() || IP == "61.172.240.227" || IP == "61.172.240.228") return true;

            return false;
        }

        /// 是否是本地或者测试ip
        /// <summary>
        /// 是否是本地或者测试ip
        /// </summary>
        /// <returns></returns>
        public static Boolean IsLocal()
        {
            string IP = GetClientIP();
            if (IP == "127.0.0.1" || IP == "::1") return true;
            return false;
        }

        /// 模拟post提交 
        /// <summary>
        /// 模拟post提交 
        /// </summary>
        /// <param name="webResponse"></param>
        /// <returns></returns>
        public static string PostURL(string url, string PostData)
        {

            HttpWebRequest hwr = WebRequest.Create(url) as HttpWebRequest;
            hwr.Method = "POST";
            hwr.ContentType = "application/x-www-form-urlencoded";
            string postdata = PostData;

            byte[] data = Encoding.UTF8.GetBytes(postdata);
            using (Stream stream = hwr.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }
            var webResponse = hwr.GetResponse() as HttpWebResponse;

            StreamReader responseReader = null;
            string responseData = "";
            try
            {
                responseReader = new StreamReader(webResponse.GetResponseStream());
                responseData = responseReader.ReadToEnd();
            }
            catch
            {
                throw;
            }
            finally
            {
                webResponse.GetResponseStream().Close();
                responseReader.Close();
                responseReader = null;
            }
            return responseData;
        }

        /// 模拟post提交，其中data的格式如 "{\"type\":"1",\"offset\":2,\"count\":3}";
        /// <summary>
        /// 模拟post提交，其中data的格式如 "{\"type\":"1",\"offset\":2,\"count\":3}";
        /// </summary>
        /// <param name="url"></param>
        /// <param name="data"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static string GetResponseData(string url, string data, string action)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            if (action.ToUpper().Equals("POST"))
            {
                request.Method = "POST";
            }
            Stream s = request.GetRequestStream();
            byte[] b = Encoding.UTF8.GetBytes(data);
            s.Write(b, 0, b.Length);
            s.Flush();
            s.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream sr = response.GetResponseStream();
            StreamReader str = new StreamReader(sr);
            string result = str.ReadToEnd();
            return result;

        }

        /// 对象深拷贝
        /// <summary>
        /// 对象深拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static T DeepClone<T>(T source)
        {
            if (source == null)
                return default(T);
            string jsonString = CheckInfo.JsonSerializer(source);
            return CheckInfo.JsonDeserialize<T>(jsonString);
        }
    }
}